namespace ThingsGateway.Foundation
{
    /// <summary>
    /// 日志基类
    /// </summary>
    public abstract class LogNetBase : DisposableObject, ILogNet
    {

        #region Protected Fields

        /// <summary>
        /// 全部的日志类型
        /// </summary>
        protected const LogType All = LogType.None | LogType.Trace | LogType.Debug | LogType.Info | LogType.Warn | LogType.Error | LogType.Fatal;
        protected IntelligentConcurrentList<string> filterKeyword;
        protected IntelligentConcurrentQueue<LogMessageItem> logMessageItems;

        #endregion Protected Fields

        #region Protected Constructors

        /// <summary>
        /// 日志基类，实现日志存储
        /// </summary>
        protected LogNetBase()
        {
            logMessageItems = new IntelligentConcurrentQueue<LogMessageItem>(100000000);
            filterKeyword = new IntelligentConcurrentList<string>();
        }

        #endregion Protected Constructors

        #region Public Events

        public event EventHandler<LogMessageItem> BeforeOut;

        #endregion Public Events

        #region Public Properties


        #endregion Public Properties

        #region Public Methods
        protected void InvokeBeforeOut(object sender, LogMessageItem e)
        {
            BeforeOut?.Invoke(sender, e);
        }







        public void Log(LogType logType, string keyword, string message) => SaveLog(logType, keyword, message);

        #endregion Public Methods

        #region Protected Methods

        protected void AddLogItem(params LogMessageItem[] logMessageItems)
        {
            foreach (LogMessageItem logMessageItem in logMessageItems)
            {
                this.logMessageItems.Enqueue(logMessageItem);
            }
            this.StartOut();
        }

        protected void ConsoleWriteLog(LogMessageItem log)
        {
            if (log == null) return;
            Console.ForegroundColor = log.Degree != LogType.Debug ?
                (log.Degree != LogType.Info ?
                (log.Degree != LogType.Trace ?
                (log.Degree != LogType.Warn ?
                (log.Degree != LogType.Error ?
                (log.Degree != LogType.Fatal ?
                ConsoleColor.White :
                ConsoleColor.White) :
                ConsoleColor.DarkRed) :
                ConsoleColor.Red) :
                ConsoleColor.Yellow) :
                ConsoleColor.White) :
                ConsoleColor.DarkGray;
            Console.WriteLine(log);
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }

        protected LogMessageItem GetLogItem(
          LogType degree,
          string keyWord,
          string text)
        {
            return new LogMessageItem()
            {
                KeyWord = keyWord,
                Degree = degree,
                Text = text,
                ThreadId = Thread.CurrentThread.ManagedThreadId
            };
        }

        protected LogMessageItem GetQueueLogItem()
        {
            logMessageItems.TryDequeue(out LogMessageItem logMessageItem);
            return logMessageItem;
        }

        protected void SaveLog(LogType logType, string keyword, string message)
        {
            this.AddLogItem(this.GetLogItem(logType, keyword, message));
        }

        protected abstract void StartOut();

        #endregion Protected Methods
    }
}
